package cn.itsource.wechat.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpUtil;
import cn.itsource.basic.util.AjaxResult;
import cn.itsource.basic.util.RedisService;
import cn.itsource.org.domain.User;
import cn.itsource.org.mapper.UserMapper;
import cn.itsource.org.pojo.info.LoginInfo;
import cn.itsource.org.pojo.vo.LoginVo;
import cn.itsource.wechat.domain.WxUser;
import cn.itsource.wechat.mapper.WxUserMapper;
import cn.itsource.wechat.pojo.dto.BinderDto;
import cn.itsource.wechat.pojo.dto.WeChatTokenDto;
import cn.itsource.wechat.pojo.dto.WechartUserInfoDto;
import cn.itsource.wechat.pojo.info.WeChatProperties;
import cn.itsource.wechat.service.IWxChatService;
import cn.itsource.wechat.service.IWxUserService;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class WxChatServiceImpl implements IWxChatService {

    @Autowired
    private WeChatProperties weChatProperties;
    @Autowired
    private IWxUserService wxUserService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private WxUserMapper wxUserMapper;
    @Autowired
    private RedisService redisService;

    @Override
    public String login() {
        //-----------------------------三部曲,跳转扫码页面,扫码之后自动回调callback,会传递code------------------------------------

        //获取到跳转到扫码页面的地址
        String codeUrl = weChatProperties.getAuthorizationCodeUrl();
        //https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_login&state=%s#wechat_redirect
        System.out.println(codeUrl);

        //转换url,把值替换占位符%s
        String url = String.format(codeUrl, weChatProperties.getAppId(), weChatProperties.getRedirectUri(), IdUtil.fastSimpleUUID());

        System.out.println(url);
        //重定向  springmvc第二天学的
        return "redirect:" + url;
    }

    @Override
    public String callback(String code) {
        //----------------------------步骤2:根据code获取access_token------------------------------------------------
        //1.拿到获取token的url
        String tokenUrl = weChatProperties.getTokenUrl();
        //2.替换%s
        String url = String.format(tokenUrl, weChatProperties.getAppId(), weChatProperties.getAppSecrect(), code);
        log.info("url:{}", url);
        //3.通过java代码调用这个url
        String result = HttpUtil.get(url);
        //result:{"access_token":"61_JoKprxxGFdw_G_O7LjFy0Ww_bOAaR7CEEbScWlgGcYLEHq4woKqnyHiUl-VaZJeyJOvFWPWMJ4RVg3ZVRI4rRL1QzeqAMDlvCm8tpfAm9N8","expires_in":7200,"refresh_token":"61_JNiO3Lfy9llU8ckkWTkZb_8RjdXivZzKwdzU0iYYQHZQWOcIlgFWGSaYnNN44L_aH8BQ9bwtqNNg6Ure2F3eKZaLByRBox9YjsZAb-CHDaM","openid":"oa9wA08wFUAASzeAjvcJupLXTVZg","scope":"snsapi_login","unionid":"ovnCWw9QMcFGNIK3bT11v6GhTCSc"}
        log.info("result:{}", result);

        //4.把json字符串转成对象WechartTokenDto
        WeChatTokenDto weChatTokenDto = JSONObject.parseObject(result, WeChatTokenDto.class);
        log.info("weChatTokenDto:{}", weChatTokenDto);

        //----------------------------步骤3,通过token拿到微信用户信息------------------------------------------------
        //1.拿到获取用户信息的url
        String userInfoUrl = weChatProperties.getUserinfoUrl();

        //2.替换%s 并访问 //https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s"
        String userUrl = String.format(userInfoUrl, weChatTokenDto.getAccess_token(), weChatTokenDto.getOpenid());
        String userInfoResult = HttpUtil.get(userUrl);
        log.info("userInfoResult:{}", userInfoResult);

        //3.把json字符串转成对象
        WechartUserInfoDto wechartUserInfoDto = JSONObject.parseObject(userInfoResult, WechartUserInfoDto.class);
        log.info("wechartUserInfoDto:{}", wechartUserInfoDto);


        //-------------------------------------绑定或者跳转首页-----------------------------------------------------
        /**
         * 三种情况
         *  1.啥也没有
         *     主要:新增wxuser的数据 ,跳转到绑定页面
         *  2.啥都有,直接跳转首页
         *
         *  3.感觉有又感觉没有,统一跳转到绑定页面
         */
        //处理第一种情况
        String binderUrl = "http://bugtracker.itsource.cn:8081/binder.html";

        //1.通过openid来获取wxuser表的数据
        String openid = wechartUserInfoDto.getOpenid();
        WxUser dbWxUser = wxUserService.findByOpenid(openid);
        //2.如果查不到,新增一条wxuser的数据
        if (dbWxUser == null) {
            WxUser wxUser = BeanUtil.copyProperties(wechartUserInfoDto, WxUser.class);
            //没有id新增微信用户
            wxUserService.saveOrUpdate(wxUser);
            //3.跳转(重定向)到绑定页面
            return "redirect:" + binderUrl + "?openid=" + openid;
        }
        //处理第二种情况,全部都完整的情况  直接跳转扫首页
        //1.获取userId
        Long userId = dbWxUser.getUserId();
        if (userId != null){
            //根据userId获取user对象
            User user = userMapper.selectByPrimaryKey(userId);
            if (user != null && StringUtils.isNotBlank(user.getPhone())){
                //4.把登录数据存到redis里面
                String token = IdUtil.fastSimpleUUID();
                LoginInfo loginInfo = BeanUtil.copyProperties(user, LoginInfo.class);
                redisService.setStringKeyAndValue(token,loginInfo,30);

                return "redirect:http://bugtracker.itsource.cn:8081/index.html" +
                        "?username="+user.getUsername()+"&email="+user.getEmail()+
                        "&phone="+user.getPhone()+"&token="+token;
            }
        }
        //第三种情况 全部都要去绑定页面
        return "redirect:" + binderUrl + "?openid=" + openid;
    }

    @Override
    public AjaxResult binder(BinderDto binderDto) {

        //--------------------------绑定逻辑------------------------------
        /**
         * 通过手机号查询分情况
         * 1.user表没有数据
         *   新增user表,把自增的id设置到wxuser表(通过openid去匹配)
         * 2.user表有数据
         *   把user表的id设置到wxuser表的外键上面
         */

        //自己去通过验证码

        //1.根据手机号查询user表的数据
        User byPhone = userMapper.findByPhone(binderDto.getPhone());
        //2.如果byPhone没有数据
        Long userId = null;
        User user = null;
        if (byPhone == null) {
            //2.1新增user表的数据
            User user1 = new User();
            user1.setPhone(binderDto.getPhone());
            user1.setPassword("123");
            //2.2加盐加密
            user1.initMd5();
            userMapper.insertSelective(user1);
            //2.3获取userId
            userId = user1.getId();
            user = user1;
        } else {
            userId = byPhone.getId();
            user = byPhone;
        }

        //3.userId设置到wxuser表里面
        //3.1通过openid拿到wxuser对象
        WxUser wxUser = wxUserMapper.findByOpenid(binderDto.getOpenid());
        //3.2把userId设置进去,再进行update这个wxuser对象
        wxUser.setUserId(userId);
        wxUserMapper.updateByPrimaryKeySelective(wxUser);

        //4.把登录数据存到redis里面
        String token = IdUtil.fastSimpleUUID();
        LoginInfo loginInfo = BeanUtil.copyProperties(user, LoginInfo.class);
        redisService.setStringKeyAndValue(token,loginInfo,30);

        //5.封装LoginVo对象
        LoginVo loginVo = BeanUtil.copyProperties(user, LoginVo.class);
        loginVo.setToken(token);

        return AjaxResult.createSuccess(loginVo);
    }
}
